package com.lambkit.undertow;

import com.jfinal.config.JFinalConfig;
import com.jfinal.server.undertow.UndertowConfig;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.server.undertow.WebBuilder;
import io.undertow.servlet.Servlets;
import io.undertow.servlet.api.FilterInfo;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import java.util.function.Consumer;

public class JFUndertowServer extends UndertowServer {
	
	private UndertowCallback undertowCallback;
    private Class<?> targetClass;

    protected JFUndertowServer(UndertowConfig undertowConfig) {
        super(undertowConfig);
    }

    /**
     * 创建 LambkitUndertowServer
     *
     * 尝试使用 "undertow.txt" 以及 "undertow-pro.txt" 初始化 undertow
     * 当配置文件不存在时不抛出异常而是使用默认值进行初始化
     */
    public static JFUndertowServer create(Class<? extends JFinalConfig> jfinalConfigClass) {
        return new JFUndertowServer(new UndertowConfig(jfinalConfigClass));
    }

    public static JFUndertowServer create(String jfinalConfigClass) {
        return new JFUndertowServer(new UndertowConfig(jfinalConfigClass));
    }

    /**
     * 创建 LambkitUndertowServer
     *
     * 使用指定的配置文件及其生产环境配置文件初始化 undertow，假定指定的配置文件名为
     * "abc.txt"，其生产环境配置文件名约定为 "abc-pro.txt"
     *
     * 注意：指定的配置文件必须要存在，而约定的那个生产环境配置文件可以不必存在
     */
    public static JFUndertowServer create(Class<? extends JFinalConfig> jfinalConfigClass, String undertowConfig) {
        return new JFUndertowServer(new UndertowConfig(jfinalConfigClass, undertowConfig));
    }

    public static JFUndertowServer create(String jfinalConfigClass, String undertowConfig) {
        return new JFUndertowServer(new UndertowConfig(jfinalConfigClass, undertowConfig));
    }

    /**
     * 使用手动构建的 UndertowConfig 对象创建 LambkitUndertowServer
     */
    public static JFUndertowServer create(UndertowConfig undertowConfig) {
        return new JFUndertowServer(undertowConfig);
    }

    public JFUndertowServer configWeb(Consumer<WebBuilder> webBuilder) {
        this.webBuilder = webBuilder;
        return this;
    }
    
    public JFUndertowServer configCallback(UndertowCallback undertowCallback) {
    	this.undertowCallback = undertowCallback;
        return this;
    }

    public JFUndertowServer addHotSwapClassPrefix(String prefix) {
        config.addHotSwapClassPrefix(prefix);
        return this;
    }

    @Override
    protected void configJFinalFilter() {
    	if(undertowCallback !=null) {
    		undertowCallback.configFilter(deploymentInfo);
//    		if("default".equals(shiroType)) {
//    			ListenerInfo listenerInfo = Servlets.listener(EnvironmentLoaderListener.class);
//    	        deploymentInfo.addListener(listenerInfo);
//    		}
//    		FilterInfo shiroFilter = Servlets.filter("shiro", getShiroFilter(shiroType));
//	        shiroFilter.setAsyncSupported(true);
//	        deploymentInfo.addFilter(shiroFilter).addFilterUrlMapping("shiro", "/*", DispatcherType.REQUEST);
    	}

//        String filter = JFLambkit.getLambkitConfig().getFilter();
//        if(StrUtil.isNotBlank(filter)) {
//            String[] filters = filter.trim().split(";");
//            for (String webFilter : filters) {
//                if (StrUtil.isNotBlank(webFilter)) {
//                    String[] webFilters = webFilter.trim().split(",");
//                    if(webFilters.length==3) {
//                        FilterInfo filterInfo = Servlets.filter(webFilters[0], getFilter(webFilters[1]));
//                        filterInfo.setAsyncSupported(true);
//                        deploymentInfo.addFilter(filterInfo).addFilterUrlMapping(webFilters[0], webFilters[2], DispatcherType.REQUEST);
//                    }
//                }
//            }
//        }

        FilterInfo filterInfo = Servlets.filter("jfinal", getJFinalFilter());
        //加入异步支持
        filterInfo.setAsyncSupported(true);
        //Printer.print(this, "starter", "filterInfo.setAsyncSupported(true);//加入异步支持");
        filterInfo.addInitParam("configClass", config.getJFinalConfig());
        deploymentInfo.addFilter(filterInfo).addFilterUrlMapping("jfinal", "/*", DispatcherType.REQUEST);
    }

    private Class<? extends Filter> getFilter(String clazz) {
        try {
            return (Class<? extends Filter>)config.getClassLoader().loadClass(clazz);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

//    private Class<? extends Filter> getShiroFilter(String shiroType) {
//        try {
//        	if("lambkit".equals(shiroType)) {
//        		return (Class<? extends Filter>)config.getClassLoader().loadClass("com.lambkit.component.shiro.LambkitShiroFilter");
//        	} else {
//        		return (Class<? extends Filter>)config.getClassLoader().loadClass("org.apache.shiro.web.servlet.ShiroFilter");
//        	}
//        } catch (ClassNotFoundException e) {
//            throw new RuntimeException(e);
//        }
//    }

    private Class<? extends Filter> getJFinalFilter() {
        try {
            return (Class<? extends Filter>)config.getClassLoader().loadClass("com.jfinal.core.JFinalFilter");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public Class<?> getTargetClass() {
        return targetClass;
    }

    public void setTargetClass(Class<?> targetClass) {
        this.targetClass = targetClass;
    }
}
